/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package com.android1.amarena2d.engine;

import com.badlogic.gdx.*;

public class AmarenaEngine extends EngineObject implements ApplicationListener {

    public static boolean DEBUG = false;

    protected Application application;
    protected Config config;

    protected TextureManager textureManager;
    protected BitmapFontManager fontManager;
    protected EventBus eventBus;
    protected Director director;
    protected AmarenaRenderer renderer;
    protected AudioManager audioManager;
    protected Scheduler scheduler;
    protected ActionManager actionManager;
    protected TouchSpotSystem touchSpotSystem;
    protected GarbageManager garbageManager;
    protected LibrarySystem librarySystem;
    protected CollisionManager collisionManager;
    protected AmarenaInputProcessor inputProcessor;
    protected ContextManager contextManager;
    protected ResourceManager resourceManager;

    boolean bootstraped = false;

    public float deltaTime;
    public float time;

    public AmarenaEngine() {
    }

    public AmarenaEngine(Application application) {
        this(application, new Config());
    }

    public AmarenaEngine(Application application, Config config) {
        init(application, config);
    }

    public void init(Application application, Config config) {

        this.application = application;
        this.config = config;

        EngineObject.engine = this;

        this.director = new Director();
        this.textureManager = new TextureManager();
        this.fontManager = new BitmapFontManager();
        this.eventBus = new EventBus();
        this.renderer = new AmarenaRenderer();
        this.audioManager = new AudioManager();
        this.scheduler = new Scheduler();
        this.actionManager = new ActionManager();
        this.inputProcessor = new AmarenaInputProcessor(this.application.getInput());
        this.touchSpotSystem = new TouchSpotSystem();
        this.garbageManager = new GarbageManager();
        this.librarySystem = new LibrarySystem();
        this.collisionManager = new CollisionManagerImpl();
        this.contextManager = new ContextManager();
        this.resourceManager = new ResourceManager();

        this.bootstraped = true;
    }

    public void onSurfaceCreated() {

    }

    public void onSurfaceChanged(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void dispose() {
        if (SpriteBatchInstance.isInstance())
            SpriteBatchInstance.dispose();
        engine.renderer.dispose();
        EngineObject.engine = null;
    }

    @Override
    public void create() {
        engine.renderer.surfaceCreated();
        engine.onSurfaceCreated();
    }

    @Override
    public void resume() {
        contextManager.notifyContextLoss();
    }

    @Override
    public void render() {
        engine.renderer.update();
    }

    @Override
    public void resize(int width, int height) {
        engine.renderer.surfaceChanged(width, height);
        engine.onSurfaceChanged(width, height);
    }

    public boolean isBootstraped() {
        return bootstraped;
    }

    void onTick(final float d) {

        deltaTime = director.timeScale * d;
        time += deltaTime;

        if (AmarenaEngine.DEBUG) {
            deltaTime = 0.16F;
        }

        director.tick();

        scheduler.tick(deltaTime);
        actionManager.tick(deltaTime);
        collisionManager.tick();

    }

    public float getDeltaTime() {
        return deltaTime;
    }

    public float getTime() {
        return time;
    }

    public Config getConfig() {
        return config;
    }

    public Director getDirector() {
        return director;
    }

    public Graphics getGraphics() {
        return application.getGraphics();
    }

    public AmarenaCamera getCamera() {
        return renderer.getCamera();
    }

    public Audio getAudio() {
        return application.getAudio();
    }

    public AudioManager getAudioManager() {
        return audioManager;
    }

    public Input getInput() {
        return application.getInput();
    }

    public ResourceManager getResourceManager() {
        return resourceManager;
    }

    public Files getFiles() {
        return application.getFiles();
    }

    public void log(String tag, String message) {
        application.log(tag, message);
    }

    public Application.ApplicationType getType() {
        return application.getType();
    }

    public TextureManager getTextureManager() {
        return textureManager;
    }

    public EventBus getEventBus() {
        return eventBus;
    }

    public AmarenaRenderer getRenderer() {
        return renderer;
    }

    public Scheduler getScheduler() {
        return scheduler;
    }

    public ActionManager getActionManager() {
        return actionManager;
    }

    public TouchSpotSystem getTouchSpotSystem() {
        return touchSpotSystem;
    }

    public GarbageManager getGarbageManager() {
        return garbageManager;
    }

    public BitmapFontManager getFontManager() {
        return fontManager;
    }

    public LibrarySystem getLibrary() {
        return librarySystem;
    }

    public CollisionManager getCollisionManager() {
        return collisionManager;
    }

    public AmarenaInputProcessor getInputProcessor() {
        return inputProcessor;
    }

    public ContextManager getContextManager() {
        return contextManager;
    }

//    //todo should find a better place for those
//    public static float getCenterX() {
//        return engine.getCamera().getScreenToWorldX(engine.getGraphics().getWidth() / 2);
//    }
//
//    public static float getCenterY() {
//        return engine.getCamera().getScreenToWorldY(engine.getGraphics().getHeight() / 2);
//    }

    public void setDebug(boolean debug) {
        AmarenaEngine.DEBUG = debug;
    }


}
